<?php

class Client extends AppModel
{

	public $name = 'Client';

	public $displayField = 'name';

	public $validate = array(
        'name' => array(
            'create_first' => array(
                'on' => 'create',
                'required' => true,
                'allowEmpty' => false,
                'message' => 'Client.name.required',
            ),
            'update_first' => array(
                'on' => 'update',
                'required' => false,
                'allowEmpty' => false,
                'message' => 'Client.name.required',
            ),
            'second' => array(
                'rule' => array('maxLength', 255),
                'message' => 'too long',
            ),
            'second2' => array(
                'rule' => array('allowName'),
                'message' => 'Client.name.must_be_unique',
            ),
        ),
        'tools' => array(
            'second2' => array(
                'rule' => array('allowTools'),
                'message' => 'Client.tools',
            ),
        ),
        'reg_code' => array(
            'second' => array(
                'rule' => array('numeric'),
                'message' => 'reg_code',
            ),
            'second2' => array(
                'rule' => array('lengthBetween', 5, 30),
                'message' => 'reg_code',
            ),
        ),
        'contract' => array(
            'second2' => array(
                'rule' => array('maxLength', 255),
                'message' => 'too long',
            ),
        ),
        'contract_start_date' => array(
            'second2' => array(
                'rule' => array('sqlDate'),
                'message' => 'date',
            ),
        ),
        'contract_finish_date' => array(
            'second2' => array(
                'rule' => array('sqlDate'),
                'message' => 'date',
            ),
        ),
        'contact_person_name' => array(
            'second2' => array(
                'rule' => array('maxLength', 255),
                'message' => 'too long',
            ),
        ),
        'contact_person_city' => array(
            'second2' => array(
                'rule' => array('maxLength', 255),
                'message' => 'too long',
            ),
        ),
        'contact_person_tel' => array(
            'second2' => array(
                'rule' => array('maxLength', 15),
                'message' => 'too long',
            ),
        ),
        'contact_person_email' => array(
            'second' => array(
                'rule' => array('maxLength', 100),
                'message' => 'too long',
            ),
            'second2' => array(
                'rule' => array('email', false),
                'message' => 'email',
            ),
        ),
        'contact_person_juridical_address' => array()
	);

	public $hasMany = array(
        'ClientAdmins' => array('className' => 'ClientAdmin', 'dependent'=>true),
        'CandidateGroups' => array('className' => 'CandidateGroup', 'dependent'=>true),

	);

	public $hasAndBelongsToMany = array(
        'Tests'=> array('className' => 'Test'),
	);

    function allowName($data)
    {
        $this->rel();
        return ! is_array($this->find(array("`{$this->primaryKey}`" => "!=".intval($this->id), "`name`" => $data)));
    }

	function allowDelete($fields = null)
	{
        return false;
	}

	function allowUpdate($fields = null)
	{
        return true;
	}

	function allowTools($data)
	{
	    if (! is_array($data)) {
	        $data = array($data);
	    }
        $Test =&  $this->getModel('Test');
        foreach ($data as $v) {
            $Test->rel();
            if (! $Test->read(null, $v)) {
                return false;
            }
        }
        $this->data['Tests']['Tests'] = $data;
        unset($this->data[$this->name]['tools']);
        return true;
	}

	function afterSave($created)
	{
	    if ($created) {
	        if (!($id = $this->getInsertID())) {
	            return false;
	        }
	        $data = array();
	        $model =& $this->getModel('CandidateGroup');
	        $modelName = $model->name;
	        $data[$modelName]['client_id'] = $id;
	        $data[$modelName]['name'] = 'Candidates';
	        $data[$modelName]['system'] = 'Y';
            $model->save($model->create($data));
	    }
	}

	function modifyRow(&$row, $primary)
	{
	    if ($primary) {
	        if (isset($row[$this->primaryKey])) {
                foreach ($this->getToolsFor($row[$this->primaryKey]) as $item) {
                    $row['tools'][] = $item['Test']['id'];
                }
	        }
	    }
	}

	function getToolsFor($id)
	{
	    if (! isset($this->hasAndBelongsToMany["Tests"])) {
	        return array();
	    }
	    $result = array();
        $this->rel('Tests');
        $r =& $this->findAll(array("`{$this->name}`.`{$this->primaryKey}`" => $id));

        if (isset($r[0]['Tests']) && is_array($r[0]['Tests'])) {
            foreach ($r[0]['Tests'] as $row) {
                $result[]['Test'] = $row;
            }
        }

        return $result;
	}

	/**
	 * Возвращает сумму, имеющююся на счету клиента.
	 *
	 * @param int $id Идентификатор клиента
	 * @return DomainAmount
	 */
	function getBalance($id)
	{
	    $this->rel();
	    $result = $this->read($this->name.'.balance', $id);
	    if (!isset($result[$this->name]['balance'])) {
	        throw new Exception();
	    }
	    return DomainAmount($result[$this->name]['balance']);
	}

	/**
	 * Возвращает сумму, доступную данному клиенту.
	 *
	 * @param int $id Идентификатор клиента
	 * @param int[optional] $testing_id Идентификатор тестинга, который не учитывыается
	 * @return DomainAmount
	 */
	function getFreeBalance($id, $testing_id = null)
	{
	    $result = bc::sub($this->getBalance($id)->value, $this->getReservedBalance($id, $testing_id)->value);
	    if (bc::lt($result, '0')) {
	        $result = '0'; //???
	    }
	    return DomainAmount($result);
	}

	/**
	 * Возвращает сумму, зарезервированную системой.
	 *
	 * @param int $id Идентификатор клиента
	 * @param int[optional] $testing_id Идентификатор тестинга, который не учитывыается
	 * @return DomainAmount
	 */
	function getReservedBalance($id, $testing_id = null)
	{
	    $reserved = '0';

        $conds = array();
        if (isset($testing_id)) {
            $conds[]["not"]["`Testing`.`id`"] = $testing_id;
        }
        $conds[]["`Testing`.`client_id`"] = $id;
        $conds[]["`Testing`.`pass_status`"] = 'READY';

	    $Testing =& $this->getModel('Testing');   /* @var $Testing   Testing */
        $Testing->rel("Test");
        $testings = $Testing->findAll($conds);
        $testings = !empty($testings) ? $testings : array();

	    foreach ($testings as $testing) {
            $reserved = bc::add($reserved, $testing['Test']['price_test']);
	    }

	    return DomainAmount($reserved);
	}

	function generateList($conds = array())
	{
	    if (Auth::o()->is('client_admin')) {
            $auth_data = Auth::o()->data();
            $conds[]["`{$this->name}`.`id`"] = $auth_data['client_id'];
	    }
	    $this->rel();
        return parent::generateList($conds, $this->primaryKey, null, "{n}.{$this->name}.{$this->primaryKey}", "{n}.{$this->name}.{$this->displayField}");
	}
}

?>